home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / docs / hyper / IndexAG.lha / IndexAG / indexagui.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-08  |  53.6 KB  |  1,577 lines

  1.  
  2. /* ******************************************************************** */
  3. /* C code generated by:                            */
  4. /* Visual Arts Version 2.5                        */
  5. /* Copyright 1994-95 Danny Y. Wong  All rights reserved            */
  6. /* Calgary, Alberta (CANADA)                                    */
  7. /* Partial of the code is copyright by Jaba Development            */
  8. /* ******************************************************************** */
  9.  
  10. /*
  11.    IndexAG 
  12.    AmigaGuide context index creator
  13.    By Sebastien Boisvert
  14.    Version 2 revision 3ß
  15.    
  16.    Description:
  17.    
  18.    Purpose: To create an 'Index' node for all words/links on an
  19.             AmigaGuide document in their context(s)
  20.             
  21.    Options:
  22.         Wordfile: list of words to ignore; one word per line,
  23.                   semi-conlon (;) as first chararcter are comments
  24.         
  25.         NOLINKS:  do not include internal/external links in Index node
  26.         
  27.         NOWORDS: do not incluce words in Index nodes
  28.         
  29.         Threshold: maximum times a word is allowed to repeat in a node
  30.                    before it is too repetitive and omitted
  31.         
  32.         COMMENT: for words that exceed the threshold, comment them so
  33.                  the author can decide to include it or not later
  34.         
  35.         GroupStart/GroupEnd: sequence of characters that determine the
  36.                              start/end of word groups
  37.    
  38.    General Operation: Reads the word list (if NOWORDS is not set). Opens
  39.         the document and proceeds to scan words/links within set parameters
  40.         and catalogs them. As they are catalogued, it is added to the list
  41.         for the node they are in, unless already present. Once done, 
  42.         produces the index in alphabetical order, check that the links are
  43.         valid as it goes along.
  44.         
  45. */
  46.  
  47. #define DEBUG 0
  48.  
  49. /* debug 1 = see each word/node/link as we go along */
  50. /* debug 2 = see each deallocation */
  51. /* debug >2 make a memory report */
  52.  
  53. #include <exec/memory.h>
  54. #include <exec/lists.h>
  55. #include <exec/nodes.h>
  56. #include <exec/types.h>
  57. #include <stdio.h>
  58. #include <string.h>
  59. #include <stdlib.h>
  60. #include <ctype.h>
  61.  
  62. #include <proto/dos.h>
  63. #include <clib/dos_protos.h>
  64. #include <clib/alib_protos.h>
  65. #include <clib/exec_protos.h>
  66.  
  67. #include "strip.h"
  68.  
  69. #if DEBUG ==3
  70. # define MWDEBUG 1
  71. # include "sc:extras/memlib/memwatch.h"
  72. #endif
  73.  
  74. #define VERSIONNUMBER "2.3ß"
  75.  
  76. long __oslibversion = 37;
  77.  
  78. char VersionString[] = "$VER: IndexAG "VERSIONNUMBER" ©1999 by Sébastien Boisvert ("__DATE__")";
  79.  
  80. struct MinList *nodelist=NULL;  /* Points to the nodes list */
  81. struct MinList *linklist=NULL;  /* Points to the links list */
  82. struct List *exwords=NULL;   /* Points to the excluded words list */
  83.  
  84. struct treenode         /* tree structure */
  85. {
  86.         struct treenode *leftptr;   /* pointer to left */
  87.         struct word *text;                 /* contains pointer to direct name of link/word */
  88.         BOOL type;                  /* identifies it as a word (TRUE) or link (FALSE) */
  89.         struct treenode *rightptr;
  90. };
  91.  
  92. struct word     /* Word structure */
  93. {
  94.         struct MinNode nextword;
  95.         char    *name;          /* the string */
  96.         struct node *node;      /* the node it belongs to */
  97.         WORD   linenumber;    /* its linenumber in the node */
  98.         WORD   count;         /* the count */
  99. };
  100.  
  101. struct node      /* Node structure */
  102. {
  103.         struct MinNode nextnode;
  104.         WORD   words;            /* number of words in node */
  105.         char   *title;             /* Node title string */
  106.         char  *name;             /* Node name string */
  107.         struct MinList *wordlist; /* pointer to its words */   
  108. };
  109.  
  110. struct link      /* Link structure */
  111. {
  112.         struct MinNode nextlink;
  113.         char *name;    /* the name */
  114.         char  *node;   /* the name of the node it references */
  115.         WORD   linenumber;    /* the line number associated with the link, if any */
  116. };
  117.  
  118. struct xword
  119. {
  120.    struct Node nextxword;
  121. };
  122.  
  123. unsigned char *AGget(BPTR, char *, int);
  124. void makeindexfile(void);
  125. void error(char *);
  126. void togglemx(void);
  127. void toggleck(void);    
  128. char *tempword;
  129. __aligned struct FileInfoBlock Fileinfo;
  130. long filepos, filesize;
  131. BPTR Filelock;
  132. UBYTE currentline;
  133. UBYTE currentnode;
  134. char buffer[513]="";
  135. UBYTE threshold;
  136. BOOL nowords,nolinks,comment,wbmode;
  137. char groupstart[5]="";
  138. char groupend[5]="";
  139. char GuideName[80];
  140. char Guidepath[80] = "";
  141. char Wordpath[80]="";
  142. char WordFile[80]="IndexAG.words";
  143. BPTR masterfile;
  144. BPTR outfile;
  145. int spacing;
  146. int lines;
  147. int ListViewitem;
  148. struct treenode *treeptr = NULL;
  149. char alpha = 64;
  150. BOOL newpress = FALSE;
  151. void Freexwords(void);
  152. int readwords(void);
  153. int readarguments(void);
  154. int scannode(void);
  155. int scanword(char *, const struct node *);
  156. void cleanup(void);
  157. int doublex(const struct node*, char *);
  158.  
  159. #include <VisualArts.h>
  160. #include <clib/VisualArts_protos.h>
  161.  
  162. #define ID_butSave                                    0
  163. #define ID_butNew                                     1
  164. #define ID_butCreate                                  2
  165. #define ID_butDelete                                  3
  166. #define ID_strFile                                    4
  167. #define ID_intThres                                   5
  168. #define ID_strWord                                    6
  169. #define ID_strStart                                   7
  170. #define ID_strEnd                                     8
  171. #define ID_strExword                                  9
  172. #define ID_chkComment                                 10
  173. #define ID_mxLinks                                    11
  174. #define ID_listExclude                                    12
  175. #define ID_lblStatus                                  13
  176.  
  177. #define IndexAGuiNumGads                        14
  178. #define ID_butFile                                    14
  179. #define ID_butWords19                                 15
  180.  
  181. #include "indexagui_func.c" 
  182.  
  183. #include "indexagui_images.c" 
  184.  
  185. int butSaveObj(struct VAobject VAObject);
  186. int butNewObj(struct VAobject VAObject);
  187. int butCreateObj(struct VAobject VAObject);
  188. int butDeleteObj(struct VAobject VAObject);
  189. int strFileObj(struct VAobject VAObject);
  190. int intThresObj(struct VAobject VAObject);
  191. int strWordObj(struct VAobject VAObject);
  192. int strStartObj(struct VAobject VAObject);
  193. int strEndObj(struct VAobject VAObject);
  194. int strExwordObj(struct VAobject VAObject);
  195. int chkCommentObj(struct VAobject VAObject);
  196. int mxLinksObj(struct VAobject VAObject);
  197. int listExclude(struct VAobject VAObject);
  198. int butFileObj(struct VAobject VAObject);
  199. int butWords19Obj(struct VAobject VAObject);
  200.  
  201. int GetPubScreen(void);
  202. void ClosePubScreen(void);
  203. int OpenIndexAGuiWindow(char windtitle[]);
  204. void CloseIndexAGuiWindow(void);
  205. int IndexAGuiHandler(void);
  206. int IndexAGuiMainHandler(void);
  207. void DrawIndexAGuiObjs(void);
  208. int main(int argc, char *argv[]);
  209.  
  210. UBYTE                *PubScrName = "Workbench";
  211. struct DrawInfo            *ScrDrawInfo = NULL;
  212. APTR                 VisualInfo = NULL;
  213. struct Screen            *Scr = NULL;
  214. struct Window            *IndexAGuiWnd = NULL;
  215. struct Gadget            *IndexAGuiGList = NULL;
  216. struct Gadget            *IndexAGuiGadgets[IndexAGuiNumGads];
  217. struct IntuiMessage         IndexAGuiMsg;
  218. UWORD                 IndexAGuiLeft = 249;
  219. UWORD                 IndexAGuiTop = 121;
  220. UWORD                 IndexAGuiWidth = 265;
  221. UWORD                 IndexAGuiHeight = 315;
  222.  
  223. /* stringinfo for WB 1.x style string/integer gadgets */
  224.  
  225. struct StringExtend            IndexAGuiStrExt;    /* Extend String Gadget */
  226. struct TextAttr topaz8 = { (STRPTR)"topaz.font", 8, 0x00, 0x01 };
  227. struct TextAttr topaz800 = { (STRPTR)"topaz.font", 8, 0x00, 0x00 };
  228.         
  229. struct IntuiText mytext;
  230.  
  231. UBYTE *linksLabels[] = {
  232.     (UBYTE *)"N_o links", 
  233.     (UBYTE *)"N_o words", 
  234.     NULL
  235. };
  236.  
  237. WORD IndexAGuiGadTypes[] = {
  238.     BUTTON_KIND,
  239.     BUTTON_KIND,
  240.     BUTTON_KIND,
  241.     BUTTON_KIND,
  242.     STRING_KIND,
  243.     INTEGER_KIND,
  244.     STRING_KIND,
  245.     STRING_KIND,
  246.     STRING_KIND,
  247.     STRING_KIND,
  248.     CHECKBOX_KIND,
  249.     MX_KIND,
  250.     LISTVIEW_KIND,
  251.     TEXT_KIND,
  252. };
  253.  
  254. struct NewGadget IndexAGuiNGads[] = {
  255.     96, 245, 60, 14, (UBYTE *)"Sa_ve",&topaz800, ID_butSave, PLACETEXT_IN, NULL, (APTR)butSaveObj,
  256.     24, 245, 60, 14, (UBYTE *)"_New",&topaz800, ID_butNew, PLACETEXT_IN, NULL, (APTR)butNewObj,
  257.     71, 276, 113, 19, (UBYTE *)"Create _Index",&topaz800, ID_butCreate, PLACETEXT_IN, NULL, (APTR)butCreateObj,
  258.     168, 245, 63, 14, (UBYTE *)"_Delete",&topaz800, ID_butDelete, PLACETEXT_IN, NULL, (APTR)butDeleteObj,
  259.     85, 53, 135, 14, (UBYTE *)"_File", &topaz800, ID_strFile, PLACETEXT_LEFT, NULL, (APTR)strFileObj,
  260.     85, 92, 63, 14, (UBYTE *)"_Threshold", &topaz800, ID_intThres, PLACETEXT_LEFT, NULL, (APTR)intThresObj,
  261.     85, 73, 135, 14, (UBYTE *)"_Word File", &topaz800, ID_strWord, PLACETEXT_LEFT, NULL, (APTR)strWordObj,
  262.     165, 112, 77, 14, (UBYTE *)"_Start", &topaz800, ID_strStart, PLACETEXT_LEFT, NULL, (APTR)strStartObj,
  263.     165, 128, 77, 14, (UBYTE *)"_End", &topaz800, ID_strEnd, PLACETEXT_LEFT, NULL, (APTR)strEndObj,
  264.     13, 244, 228, 15, (UBYTE *)"", &topaz800, ID_strExword, PLACETEXT_LEFT, NULL, (APTR)strExwordObj,
  265.     163, 94, 26, 11, (UBYTE *)"_Comment", &topaz800, ID_chkComment, PLACETEXT_RIGHT, NULL, (APTR)chkCommentObj,
  266.     18, 115, 17, 9, (UBYTE *)"", &topaz800, ID_mxLinks, PLACETEXT_RIGHT, NULL, (APTR)mxLinksObj,
  267.     13, 160, 228, 84, (UBYTE *)"Exclude words", &topaz800, ID_listExclude, PLACETEXT_ABOVE, NULL, (APTR)listExclude,
  268.     9, 9, 239, 25, (UBYTE *)"Status", &topaz800, ID_lblStatus, PLACETEXT_BELOW, NULL, NULL,
  269. };
  270.  
  271. ULONG IndexAGuiNTags[] = {
  272.     (GT_Underscore), '_', TAG_DONE,
  273.     (GT_Underscore), '_', TAG_DONE,
  274.     (GT_Underscore), '_', TAG_DONE,
  275.     (GT_Underscore), '_', TAG_DONE,
  276.     (GT_Underscore), '_', GTST_MaxChars, 80, (STRINGA_Justification), GACT_STRINGLEFT, (GA_TabCycle), TRUE, TAG_DONE,
  277.     (GT_Underscore), '_', (GTIN_MaxChars), 10, (STRINGA_Justification), GACT_STRINGLEFT, (GA_TabCycle), TRUE, TAG_DONE,
  278.     (GT_Underscore), '_', GTST_String, (ULONG)WordFile, GTST_MaxChars, 80, (STRINGA_Justification), GACT_STRINGLEFT, (GA_TabCycle), TRUE, TAG_DONE,
  279.     (GT_Underscore), '_', GTST_MaxChars, 5, (STRINGA_Justification), GACT_STRINGLEFT, (GA_TabCycle), TRUE, TAG_DONE,
  280.     (GT_Underscore), '_', GTST_MaxChars, 5, (STRINGA_Justification), GACT_STRINGLEFT, (GA_TabCycle), TRUE, TAG_DONE,
  281.     (GT_Underscore), '_', (GA_Disabled), TRUE, GTST_MaxChars, 30, (STRINGA_Justification), GACT_STRINGLEFT, TAG_DONE,
  282.     (GT_Underscore), '_', (GTCB_Checked), FALSE, TAG_DONE,
  283.     (GT_Underscore), '_', (GTMX_Labels), (ULONG)&linksLabels[0], (GTMX_Active), 0, (GTMX_Spacing), 4, TAG_DONE,
  284.     (GTLV_ShowSelected), 99, (GTLV_Labels), NULL, (GTLV_Top), 0, (GTLV_ScrollWidth), 16, (LAYOUTA_Spacing), 0, TAG_DONE,
  285.     (GTTX_Text),(ULONG)"", (GTTX_Border), TRUE, TAG_DONE,
  286. };
  287.  
  288. struct Gadget butFileGad = {
  289.     NULL, 227, 62, 22, 17, 
  290.     GFLG_GADGHIMAGE | GFLG_GADGIMAGE, GACT_RELVERIFY ,
  291.     GTYP_BOOLGADGET, (APTR)&PopFile_mf0Image, (APTR)&PopFile_mf1Image, NULL, 0x0, NULL,
  292.     ID_butFile, (APTR)butFileObj
  293. };
  294.  
  295. struct Gadget butWords19Gad = {
  296.     &butFileGad, 227, 82, 22, 17, 
  297.     GFLG_GADGHIMAGE | GFLG_GADGIMAGE, GACT_RELVERIFY ,
  298.     GTYP_BOOLGADGET, (APTR)&PopFile_mf0Image, (APTR)&PopFile_mf1Image, NULL, 0x0, NULL,
  299.     ID_butWords19, (APTR)butWords19Obj
  300. };
  301.  
  302.  
  303. void __regargs __chkabort(void)   /* disables CTRL_C */
  304. {}
  305.         
  306. void error(char *error)
  307. {
  308.         __aligned struct EasyStruct errorstruct = { sizeof(struct EasyStruct), 0, "IndexAG Error", "%s", "OK",};
  309.                 
  310.         if (wbmode==TRUE)
  311.                 EasyRequest(IndexAGuiWnd, &errorstruct, NULL, error);
  312.         else 
  313.                 printf("%s", error);
  314. }
  315.  
  316.  
  317. int readwords(void)
  318. {
  319.    void freexwords(void);
  320.    void SortMinList(struct List *mlh);
  321.    BPTR wordfilehandle;
  322.    struct xword *word1;
  323.    void *temp;
  324.    char file[160];
  325.    strcpy(file,Wordpath);
  326.    AddPart(file, WordFile, 160);
  327.    freexwords();
  328.    
  329.    if(!(wordfilehandle=Open(file,MODE_OLDFILE)))       /* Open our word file */
  330.    {
  331.      char errorstr[80]="Could not open word file ";
  332.      strcat (errorstr, WordFile);
  333.      strcat (errorstr, "!\n");
  334.      error(errorstr);
  335.      exwords=NULL;
  336.      return 0;
  337.    }
  338.    else
  339.    {
  340.       if (!(exwords=AllocMem(sizeof(struct List), MEMF_CLEAR)))      /* Allocate memory for the list header */
  341.         error("Not enough memory for wordlist\n");
  342.       else
  343.       {
  344.         
  345.         NewList((struct List *)exwords);
  346.       
  347.         /* We start adding words here */
  348.       
  349.       FGets(wordfilehandle, buffer, 513);      /* Prime loop */
  350.       do
  351.       {
  352.         strip(buffer, "\n", 'E');
  353.          if (buffer[0] != ';' && buffer != "")  /* If it's not a comment line and not empty*/
  354.          {
  355.            if (!(word1=AllocMem(sizeof(struct xword),MEMF_CLEAR)))  /* Allocate space for the node */
  356.               error("Not enough memory for newword structure\n");
  357.            else
  358.            {
  359.               if (!(temp=AllocMem(strlen(buffer)+1, MEMF_CLEAR)))  /* Allocate for the word - buffer has extra \n !! */
  360.                  error("Not enough memory to store word\n");
  361.               else
  362.               {
  363.                   word1->nextxword.ln_Name = temp;                         /* point our word pointer to the memory allocated */
  364.                   strncpy(word1->nextxword.ln_Name, buffer, strlen(buffer));
  365.                   AddTail((struct List *)exwords, (struct Node *)word1);  /* add it to the list */
  366.               }
  367.            }
  368.          }
  369.           /* get next word */
  370.       }while(FGets(wordfilehandle, buffer, 513));        /* repeat until done reading */
  371.       }
  372.       Close(wordfilehandle);
  373.  
  374.    SortMinList(exwords);
  375.  
  376.    return 1;
  377.    }
  378. }
  379.  
  380. /*------------------------------------------------------------------------*/
  381. /*                                                                        *
  382.  *  $Id: sortminlist.c 1.1 1996/09/15 07:42:23 heinz Exp $
  383.  *                                                                        */
  384. /*------------------------------------------------------------------------*/
  385.  
  386. /*------------------------------------------------------------------------*/
  387. /*
  388.  * A simple Insertion Sort based MinList sort function with a test case
  389.  * (C)1996 by Heinz Wrobel, <heinz@hwg.muc.de>
  390.  *
  391.  * Based on SAS/C 6.56. Use a command line like this to check this out:
  392.  *  SC $*.c LINK DEF=TEST
  393.  */
  394. /*------------------------------------------------------------------------*/
  395.  
  396. /*------------------------------------------------------------------------*/
  397. void SortMinList(struct List *lh)
  398. {
  399.     struct xword *mn1, *mn2, *mnnext;
  400.  
  401.     /* We are doing a simple insertion like sort here, working our way
  402.      * sequentially through the list. The runtime should be acceptable
  403.      * for smaller lists. MinLists are used because this is the lowest
  404.      * common denominator for all lists. I always felt that it is better
  405.      * to cast something down than to cast it upwards.
  406.      */
  407.  
  408.     /* This makes sense only if we have more than one node in the list! */
  409.     mn1 = (struct xword *)lh->lh_Head;
  410.     if(mn1->nextxword.ln_Succ)
  411.     {
  412.         /* While there is still a current node to sort in, sort it in.
  413.          * We stash the next pointer right away to avoid losing it on
  414.          * node removal. Note how we also skip the very first node!
  415.          */
  416.         for(mn1 = (struct xword *)mn1->nextxword.ln_Succ;
  417.             mnnext = (struct xword *)mn1->nextxword.ln_Succ;
  418.             mn1 = mnnext)
  419.         {
  420.             /* Work our way backwards to find
  421.              * the correct insertion point
  422.              */
  423.             for(mn2 = (struct xword *)mn1->nextxword.ln_Pred;
  424.                 mn2->nextxword.ln_Pred;
  425.                 mn2 =(struct xword *) mn2->nextxword.ln_Pred)
  426.             {
  427.                 /* Our callback must return the same values
  428.                  * strcmp would return:
  429.                  *      <0  : mn1 <  mn2
  430.                  *      =0  : mn1 == mn2
  431.                  *      >0  : mn1 >  mn2
  432.                  * We stop when we find a node that is smaller than the
  433.                  * current one and insert our node after it
  434.                  */
  435.                 if(stricmp(mn1->nextxword.ln_Name, mn2->nextxword.ln_Name) > 0)
  436.                 {
  437.                     break;
  438.                 } /* if */
  439.             } /* for */
  440.  
  441.             /* Only do something, if we are not at
  442.              * the correct position yet
  443.              */
  444.             if(mn2->nextxword.ln_Succ != (struct Node *)mn1)
  445.             {
  446.                 /* Remember how we stashed the next pointer to continue! */
  447.                 Remove((struct Node *)mn1);
  448.                 Insert((struct List *)lh,
  449.                        (struct Node *)mn1, (struct Node *)mn2);
  450.             } /* if */
  451.         } /* while */
  452.     } /* if */
  453.  
  454. } /* SortMinList */
  455.  
  456. /*------------------------------------------------------------------------*/
  457. void freexwords(void)
  458. {
  459.         struct xword *new;
  460.         void *temp;
  461.         
  462.    if(exwords)
  463.    {
  464. #if DEBUG ==2
  465.   printf("Freeing exwords\n");
  466. #endif      
  467.      for (new= (struct xword *)exwords->lh_Head; new->nextxword.ln_Succ; new=(struct xword *)exwords->lh_Head)
  468.      { 
  469. #if DEBUG ==2
  470.  printf(" Clearing word '%s' from exwords\n",new->nextxword.ln_Name);
  471. #endif
  472.          if(new->nextxword.ln_Name)
  473.           FreeMem(new->nextxword.ln_Name, strlen(new->nextxword.ln_Name)+1);   /* release size of word + the NULL */
  474.          temp=RemHead((struct List *)exwords);             /* remove node from list */
  475.          FreeMem(temp, sizeof(struct xword));              /* release memory */
  476.      }
  477. #if DEBUG ==2
  478.  printf("Freed exwords list\n\n");
  479. #endif
  480.      FreeMem(exwords, sizeof(struct List));  /* release the list */
  481.    }
  482. }
  483.       
  484. void cleanup(void)   /* Here we free the entire lists */
  485. {
  486.    
  487.    struct node *newnode;
  488.    struct word *newwrd;
  489.    struct link *newlink;
  490.    void *temp;
  491.    void freetree(struct treenode *);
  492.  
  493. if (wbmode==FALSE)
  494.         freexwords();
  495.  
  496.   if(nodelist)  /* If there's a node list */
  497.   {
  498. #if DEBUG ==2
  499.  printf("Freeing nodelist\n");
  500. #endif
  501.    for(newnode =(struct node *)nodelist->mlh_Head; newnode->nextnode.mln_Succ; newnode=(struct node *)nodelist->mlh_Head)
  502.    {
  503. #if DEBUG ==2
  504.  printf(" Clearing node:title '%s' & nodename '%s'\n", newnode->title, newnode->name);
  505. #endif
  506.       if(newnode->title)
  507.        FreeMem(newnode->title, strlen(newnode->title)+1);  /* free its name and title */
  508.       if(newnode->name)
  509.        FreeMem(newnode->name, strlen(newnode->name)+1);
  510.       if(newnode->wordlist)   /* check for wordlist */
  511.       {
  512. #if DEBUG ==2
  513.  printf("  Freeing node's wordlist\n");
  514. #endif         
  515.          for(newwrd= (struct word *)newnode->wordlist->mlh_Head; newwrd->nextword.mln_Succ; newwrd= (struct word *)newnode->wordlist->mlh_Head)
  516.          {
  517. #if DEBUG ==2
  518.   printf("   Freeing word '%s' in node's wordlist with count %d, threshold is %d\n", newwrd->name, newwrd->count, threshold);
  519. #endif
  520.             if(newwrd->name)
  521.              FreeMem(newwrd->name, strlen(newwrd->name)+1);   /* clear each word node */
  522.             temp=RemHead((struct List *)newnode->wordlist);
  523.             FreeMem(temp, sizeof(struct word));
  524.          }
  525. #if DEBUG ==2
  526.  printf("   Freed node's wordlist\n");
  527. #endif      
  528.           FreeMem(newnode->wordlist, sizeof(struct MinList));  /* free wordlist */
  529.       }
  530. #if DEBUG ==2
  531.  printf("  Freed node\n");
  532.  #endif
  533.       temp=RemHead((struct List *)nodelist);  /* free the node */
  534.       FreeMem(temp, sizeof(struct node));
  535.    }
  536. #if DEBUG ==2
  537.  printf("Freed nodelist\n\n");
  538. #endif
  539.    FreeMem(nodelist, sizeof(struct MinList));   /* finally free the node list */
  540.   }
  541.    
  542.    if(linklist) /* check for link list */
  543.    {
  544. #if DEBUG ==2
  545.  printf("Freeing linklist\n");
  546. #endif
  547.       for(newlink = (struct link *)linklist->mlh_Head; newlink->nextlink.mln_Succ; newlink=(struct link *)linklist->mlh_Head)
  548.       {
  549. #if DEBUG ==2
  550.  printf("  Freeing link node name '%s' from linklist %d\n", newlink->name, newlink->linenumber);        
  551. #endif
  552.          if (newlink->name)
  553.              FreeMem(newlink->name, strlen(newlink->name)+1);  /* free the link name */
  554.          if(newlink->node)
  555.              FreeMem(newlink->node, strlen(newlink->node)+1); /* free the node name and finally the node */
  556.          temp=RemHead((struct List *)linklist);
  557. #if DEBUG ==2
  558.   printf(" Freeing node from linklist\n");
  559. #endif
  560.          FreeMem(temp, sizeof(struct link));
  561.       }
  562. #if DEBUG ==2
  563.  printf("Freed linklist\n");
  564. #endif      
  565.       FreeMem(linklist, sizeof(struct MinList));   /* free the list */
  566.    }
  567.    
  568.    if(treeptr)
  569.         freetree(treeptr);      /* free the tree */
  570.          
  571. }
  572.  
  573. void freetree(struct treenode *treeptr)  /* this recursively clears the tree */
  574. {
  575.         freetree(treeptr->leftptr);
  576.         freetree(treeptr->rightptr);
  577.         FreeMem(treeptr, sizeof(struct treenode));
  578. }
  579.  
  580. int readarguments(void)      /* read in arguments form CLI */
  581. {
  582.    int result=0;
  583.    struct RDArgs *rda;
  584.    LONG options[8];
  585.    
  586.    printf("IndexAG "VERSIONNUMBER" by Sébastien Boisvert\n");
  587.  
  588.      if ((rda = AllocDosObject(DOS_RDARGS, NULL)) != NULL)
  589.      {
  590.          rda->RDA_ExtHelp = "\nFILENAME/A   name of the AmigaGuide database\n"
  591.                             "WORDFILE/K   alternate word file to use\n"
  592.                             "THRESHOLD/N  maximum number of times a word can repeat in a node\n"
  593.                             "NOWORDS/S    do not index words, only links\n"
  594.                             "NOLINKS/S    do not index links, only words. Overrides NOWORDS if both are set\n"
  595.                             "COMMENT/S    comment words that cross threshold\n"
  596.                             "GROUPSTART/K the sequence of character(s) that indicate the start of a group\n"
  597.                             "GROUPEND/K   the sequence of character(s) that indicate the end of a group\n"
  598.                             " (Both GROUPSTART and GROUPEND must be no more than 4 characters)\n"
  599.                             "Enter arguments";
  600.       
  601.       
  602.         options[0] = (LONG)"";                 /* defaults */
  603.         options[1] = (LONG)"IndexAG.words";
  604.         options[2] = NULL;
  605.         options[3] = 1;
  606.         options[4] = 0;
  607.         options[5] = 0;
  608.         options[6] = (LONG)"<";
  609.         options[7] = (LONG)">";
  610.       
  611.          if (ReadArgs("FILENAME/A,WF=WORDFILE/K,TH=THRESHOLD/N,NW=NOWORDS/S,NL=NOLINKS/S,C=COMMENT/S,GS=GROUPSTART/K,GE=GROUPEND/K", options, rda) != NULL)
  612.         {
  613.            strcpy(GuideName,(char *)options[0]);
  614.            strcpy(WordFile, (char *)options[1]);
  615.            if (options[2] != NULL)
  616.              threshold = *(LONG *)options[2];
  617.            else
  618.               threshold = 10;
  619.            nowords = options[3];
  620.            nolinks = options[4];      
  621.            comment= options[5]; 
  622.            
  623.            if (nowords && nolinks)
  624.               nowords =0;
  625.            
  626.            strncpy(groupstart,(char *)options[6], 4);
  627.            strncpy(groupend,(char *)options[7], 4);
  628.            FreeArgs(rda);
  629.            FreeDosObject(DOS_RDARGS, rda);
  630.            
  631.            result =1;  /* success */
  632.         }
  633.         else
  634.            PrintFault(IoErr(), "IndexAG");
  635.            
  636.      return result;
  637.   }
  638. }  
  639.  
  640. int scannode()
  641. {
  642.    char temptitle[80]="";
  643.    char tempname[80]="";
  644.    char *temp;
  645.       char scannodebuffer[100]="";
  646.    char *tempbuffer=scannodebuffer;
  647.    char mid[5]="";
  648.    struct node *tempnode;
  649.    struct word *tempword, *searchdouble;
  650.    long i;
  651.    
  652.    strcpy(tempname, strtok(NULL, " \""));       /* get the name of the node */
  653.    
  654.    if(!(strncmp(tempname, "\"", 1)))            /* if it's in strings extract untill next quote */
  655.    {
  656.       strcpy(tempname, tempname+1);
  657.       strcat(tempname, " ");
  658.       strcat(tempname,(strtok(NULL, "\"")));
  659.    }
  660.    
  661.    if(!(strnicmp(tempname,"INDEX", 5)))         /* check if it's the INDEX node */
  662.      return 1;                                  /* and return (skip it) if so */
  663.    
  664.    strcpy(temptitle, strtok(NULL, "\n"));       /* get the title */
  665.    
  666.    strip(tempname, " \"\n", 'B');      
  667.    strip(temptitle, " \"", 'B');
  668. #if DEBUG ==1
  669.  printf("Found node:'%s'   '%s'\n", tempname, temptitle);
  670. #endif   
  671.          
  672.       if(!(tempnode=AllocMem(sizeof(struct node), MEMF_CLEAR)))
  673.       {
  674.         error("Not enough memory to add node to the list!\n");
  675.         return 0;
  676.       }
  677.       else
  678.       {
  679.          AddTail((struct List *)nodelist, (struct Node *)tempnode);  /* add new node */
  680.          tempnode->name = NULL;
  681.          tempnode->title=NULL;
  682.          
  683.          if(!(temp=AllocMem(strlen(temptitle)+1, MEMF_CLEAR)))
  684.          {
  685.            error("Can't allocate memory for node title!\n");
  686.            return 0;
  687.          }
  688.          else
  689.          {
  690.             #if DEBUG ==1
  691.               printf("Allocated node title\n");                 /* add title */
  692.             #endif
  693.             tempnode->title=temp;
  694.             strcpy(temp, temptitle);
  695.             
  696.             if(!(temp=AllocMem(strlen(tempname)+1, MEMF_CLEAR)))
  697.             {
  698.                error("Can't allocate memory for node name!\n");
  699.                return 0;
  700.             }
  701.             else
  702.             {
  703.                #if DEBUG ==1
  704.                  printf("Allocated node name\n");       /* add name */
  705.                #endif
  706.                tempnode->name = temp;
  707.                strcpy(temp, tempname);
  708.                
  709.                tempnode->words=0;
  710.                tempnode->wordlist = NULL;       /* initialise its wordlist to NULL */
  711.                
  712.                
  713.                if (!nowords)
  714.                {
  715.                   if(!(temp=AllocMem(sizeof(struct MinList), MEMF_CLEAR)))
  716.                   {
  717.                      error("Can't allocate words list for node!\n");
  718.                      return 0;
  719.                   }
  720.                   else
  721.                   {
  722.                      #if DEBUG ==1
  723.                        printf("Allocated wordlist for node\n");         /* create word list */
  724.                      #endif
  725.                      tempnode->wordlist=(struct MinList *)temp;
  726.                      
  727.                      NewList((struct List *)tempnode->wordlist);        /* initialise list */
  728.                   }
  729.                }
  730.                                
  731.                lines=0;
  732.                    
  733.                do
  734.                {
  735.                   AGget(masterfile, buffer, 513);       /* read next line */
  736.                   if(!(strnicmp(buffer, "@ENDNODE", 7)))        /* if end of node */
  737.                      return 1;                                  /* return for next */
  738.                         
  739.                   strip(buffer, "\n", 'E');
  740.                   for(i=0; buffer[i] != NULL; i++)      /* make sure each character is printable */
  741.                     if(!(isprint(buffer[i])))           /* to validate scanning w/ strtok() */
  742.                        buffer[i]=' ';
  743.                   
  744.                   strip(tempbuffer, " ", 'B');
  745.                                 
  746.                   lines++;
  747.                      
  748.                   temp=strtok(buffer, " ");
  749.                   
  750.                         
  751.                   do
  752.                   {
  753.                     if(temp)    
  754.                     {
  755.                      strcpy(tempbuffer, temp);
  756.                                           
  757.                      /* Check for group word */
  758.                                                                
  759.                      if(!nowords && strlen(groupstart) && strlen(groupend) )
  760.                      {
  761.                        strmid(tempbuffer,mid,1,strlen(groupstart));
  762.                        if(!(stricmp(mid, groupstart)))
  763.                        {
  764.                          strmid(tempbuffer,mid,strlen(tempbuffer)-strlen(groupend),strlen(groupend));
  765.                          if(stricmp(mid,groupend))
  766.                          {
  767.                              strcat(tempbuffer, " ");   /* get full group of words */
  768.                              strcat(tempbuffer, strtok(NULL,groupend));
  769.                          }
  770.                        }  
  771.                              
  772.                        strip(tempbuffer,groupstart, 'S');
  773.                        strip(tempbuffer,groupend, 'E');
  774.                      }
  775.                            
  776.                      if(!(strncmp(tempbuffer,"@", 1)))
  777.                       if(!(scanword(tempbuffer, tempnode)))  /* check if it's a command */
  778.                           return 0;     /* return to caller if failure for cleanup() */
  779.                              
  780.                      if(temp=strchr(tempbuffer, '@'))  /* if there's a tag left over */
  781.                        if(*(++temp) == '{')             /* strip it */
  782.                           *(--temp)='\0';
  783.                      
  784.                      /* get rid of extraneous characters */
  785.                            
  786.                      strip(tempbuffer,"!#$%^&*()[]{}|,<>?;=\"`~", 'A');
  787.                      strip(tempbuffer,".'+-_:/\\ ", 'B');
  788. #if DEBUG ==1
  789.                      printf("Current buffer is:'%s' %d\n", tempbuffer, strlen(tempbuffer));
  790. #endif
  791.                      /* if we want to add words */
  792.                      
  793.                      if (!nowords && strlen(tempbuffer)!=0)
  794.                      {
  795.                         if(!(doublex(tempnode, tempbuffer))) /* check if in exclude list */
  796.                         {
  797.                                 /* check if already in current wordlist */
  798.                           for(searchdouble= (struct word *)tempnode->wordlist->mlh_Head; searchdouble ; searchdouble= (struct word *)searchdouble->nextword.mln_Succ)
  799.                               if (searchdouble->name)
  800.                               {
  801.       
  802.                                 if(!(stricmp(tempbuffer, searchdouble->name)))
  803.                                    break; 
  804.                                    
  805.                               }
  806.                           
  807.                           
  808.                           /* if not add it to list */    
  809.                           if (!searchdouble)
  810.                           {
  811.                              if(!(tempword=AllocMem(sizeof(struct word), MEMF_CLEAR)))
  812.                              {
  813.                                 error("Not enough memory to add word node to node's list\n");
  814.                                 return 0;
  815.                              }
  816.                              else
  817.                              {
  818.                                 tempword->name = NULL;
  819.                                 AddTail((struct List *)tempnode->wordlist, (struct Node *)tempword);
  820.  
  821.                                 if(!(temp=AllocMem(strlen(tempbuffer)+1, MEMF_CLEAR)))
  822.                                 {
  823.                                    error("Not enough memory to add word to node's list!\n");
  824.                                    return 0;
  825.                                 }
  826.                                 else
  827.                                 {
  828.                                    tempword->name = temp;
  829.                                    strcpy(tempword->name,tempbuffer);
  830.                                    tempword->node = tempnode;
  831.                                    tempword->linenumber=lines;
  832.                                    tempword->count=1;
  833.                                    
  834.                                    if (spacing < strlen(tempword->name))
  835.                                         spacing = strlen(tempword->name);
  836. #if DEBUG==1
  837.   printf(" Added word '%s' to node's wordlist\n", tempword->name);
  838. #endif
  839.                                 }
  840.                              }
  841.                           }
  842.                           else
  843.                              ++(searchdouble->count);   /* otherwise increase its count */
  844.                         } 
  845.                      }
  846.                    }
  847.                   }
  848.                   while (temp=strtok(NULL, " "));  /* loop back with next token */
  849.                  }
  850.                      while(1);  /* loop until EOF */
  851.                   }
  852.             }
  853.          }
  854.    return 1;
  855. }
  856.  
  857. int doublex(const struct node *node, char *string)   /* checks if word is in exclude list  */
  858. {
  859.    struct xword *xword;
  860.    for(xword=(struct xword *)exwords->lh_Head; xword->nextxword.ln_Succ; xword= (struct xword *)xword->nextxword.ln_Succ)
  861.       if(!(stricmp(xword->nextxword.ln_Name, string)))
  862.         return 1;
  863.   
  864.    return 0;
  865. }                       
  866.  
  867.  
  868. int scanword(char *tempbuffer, const struct node *node)
  869. {
  870.    char linkname[80]="";
  871.    char command[80]="";
  872.    char nodelink[80]="";
  873.    struct link *newlink;
  874.    void *temp;
  875.    char *ptr;
  876.    int tempnum;
  877.    
  878.    
  879.    if(!(strncmp(tempbuffer, "@{\"",3))) /* check if it's a link */
  880.    {
  881.       
  882.       strcpy(linkname, tempbuffer+3);           /* yes, get link name */
  883.       if(linkname[strlen(linkname)-1]!='"')
  884.       {
  885.         strcat(linkname, " ");
  886.         strcat(linkname, strtok(NULL,"\""));
  887.       }
  888.       
  889.       strcpy(command, strtok(NULL, " "));  /* get link where it points to */
  890.       strcpy(nodelink, strtok(NULL, "}"));
  891.       strip(nodelink, " ", 'E');
  892.       
  893.       ptr=strrchr(nodelink, ' ');       /* find the last space character */
  894.       
  895.       tempnum=atoi(ptr);
  896.       
  897.       if(tempnum != 0)  /* check if there's a number at the end */
  898.         *ptr='\0';
  899.          
  900.       strip(linkname, " \"", 'B');
  901.       strip(nodelink, " \"", 'B');
  902.  
  903. #if DEBUG ==1
  904.  printf("\nLink found for string '%s' to node '%s' lineref: %d\n", linkname, nodelink, tempnum);
  905. #endif      
  906.  
  907.       if(!(stricmp(command,"link")) && !nolinks)  /* if it's a link */
  908.       {
  909.         int match=0;
  910.         for(newlink= (struct link *)linklist->mlh_Head; newlink->nextlink.mln_Succ && !match; newlink = (struct link *)newlink->nextlink.mln_Succ)
  911.         {
  912.            if(!(stricmp(newlink->name, linkname)))  /* see if it's in list */
  913.               match=1;
  914.         }
  915.  
  916.         if(!match)      /* if not in list add it to links list */
  917.         {
  918.            if(!(newlink=AllocMem(sizeof(struct link), MEMF_CLEAR)))
  919.            {
  920.               error("Can't allocate memory to add link node!\n");
  921.               return 0;
  922.            }
  923.            else
  924.            {
  925.               AddTail((struct List *)linklist, (struct Node *)newlink);
  926.               newlink->name = NULL;
  927.               newlink->node = NULL;
  928.               
  929.               if(!(temp=AllocMem(strlen(linkname)+1, MEMF_CLEAR)))
  930.               {
  931.                  error("Can't allocate memory for link name!\n");
  932.                  return 0;
  933.               }
  934.               else
  935.               {
  936.                  strcpy(temp, linkname);
  937.                  newlink->name = temp;
  938.                  
  939.                  if (spacing < strlen(linkname))
  940.                         spacing = strlen(linkname);
  941.                         
  942.                  if(!(temp=AllocMem(strlen(nodelink)+1, MEMF_CLEAR)))
  943.                  {
  944.                      error("Can't allocate memory for link node!\n");
  945.                      return 0;
  946.                  }
  947.                  else
  948.                  {
  949.                         strcpy(temp, nodelink);
  950.                         newlink->node = temp;
  951.                         newlink->linenumber = tempnum;
  952.                  }
  953.               }
  954.            }
  955.         }
  956.       }
  957.      else   /* it's not an internal link, but a command; index as word (by returning to caller with name in buffer */
  958.       {
  959.         if(!nowords)
  960.         {
  961.                 strcpy(tempbuffer, linkname);
  962.                 return 1;
  963.         }
  964.       } 
  965.    }
  966.    else
  967.    {
  968.      if(!(strncmp(tempbuffer,"@{", 2)))  /* check if it's a tag */
  969.      {
  970.         char *temp;
  971.         
  972.         if(temp=strchr(tempbuffer,'}')) /* skip it and see if there's anything after it */
  973.           strcpy(tempbuffer, temp+1);
  974.           
  975.         if (strlen(tempbuffer) !=0 && tempbuffer[strlen(tempbuffer)-1] == '}')
  976.           *(strchr(tempbuffer, '@')) = '\0'; /* if there's something and it contains another */
  977.                                      /* command, stip that command */
  978.            
  979.      }
  980.      else
  981.      {
  982.         *tempbuffer='\0';  /* otherwise it's a command so skip entire line */
  983.         strtok(NULL,"\n");
  984.         lines--;                /* command lines are not counted in linking */
  985.      } 
  986.    }
  987.    
  988.    return 1;  /* success */
  989. }
  990.  
  991. int createindex(void)
  992. {
  993.         int insertnode (struct treenode **, struct word *, BOOL);
  994.         int writeindex(struct treenode *);
  995.                 
  996.         struct node *currentnode;
  997.         struct word *current;
  998.         struct link *currentlink;
  999.  
  1000.         if(!wbmode)
  1001.                 printf("\nCreating index node...\n");
  1002.         
  1003.          if(!nowords)
  1004.           for(currentnode = (struct node *)nodelist->mlh_Head; currentnode->nextnode.mln_Succ ; currentnode = (struct node *)currentnode->nextnode.mln_Succ)
  1005.                 for(current = (struct word *)currentnode->wordlist->mlh_Head; current->nextword.mln_Succ != NULL ; current = (struct word *)current->nextword.mln_Succ)
  1006.                         if(!(insertnode(&treeptr, current,  TRUE)))
  1007.                                 return 0;
  1008.  
  1009.          if(!nolinks)
  1010.           for(currentlink = (struct link *)linklist->mlh_Head; currentlink->name ; currentlink = (struct link *)currentlink->nextlink.mln_Succ)
  1011.                 if(!(insertnode(&treeptr, (struct word *)currentlink, FALSE)))
  1012.                         return 0;
  1013.                 
  1014.          if(!(writeindex(treeptr)))
  1015.                 return 0;             
  1016.                 
  1017.  return 1;       
  1018.         
  1019. }
  1020.  
  1021. int writeindex(struct treenode *tree)
  1022. {
  1023.         struct node *node;
  1024.         int i, match;
  1025.         
  1026.              if (tree != NULL)
  1027.              {
  1028.                     if(!(writeindex(tree->leftptr)))
  1029.                         return 0;
  1030.  
  1031.                     switch(tree->type)
  1032.                     {
  1033.                         case TRUE:
  1034.                                 if(!nowords)
  1035.                                 if(tree->text->count < threshold || comment)
  1036.                                 {
  1037.                                         if(toupper(tree->text->name[0]) > alpha)
  1038.                                         {
  1039.                                                 while(toupper(tree->text->name[0]) != alpha)
  1040.                                                         alpha++;
  1041.                                                 
  1042.                                                 sprintf(buffer, "\n %c\n\n", alpha);
  1043.                                                 FPuts(outfile, buffer);
  1044.                                         }               
  1045.  
  1046.                                         FPutC(outfile, (tree->text->count < threshold ? ' ' : '*'));
  1047.                                         sprintf(buffer, "@{\" %s \" link \"%s\" %d}", tree->text->name, tree->text->node->name, tree->text->linenumber);
  1048.                                         FPuts(outfile, buffer);
  1049.                                         for (i=0; i<(spacing-strlen(tree->text->name)); i++)
  1050.                                                 FPutC(outfile, ' ');
  1051.                                         sprintf(buffer, "%s\n",tree->text->node->title);
  1052.                                         FPuts(outfile, buffer);
  1053.                                 }
  1054.                                 break;
  1055.                         case FALSE:
  1056.                         
  1057.                                 if(!nolinks)
  1058.                                 {       
  1059.                                         if(toupper(tree->text->name[0]) > alpha)
  1060.                                         {
  1061.                                                 while(toupper(tree->text->name[0]) != alpha)
  1062.                                                         alpha++;
  1063.                                                 
  1064.                                                 sprintf(buffer, "\n %c\n\n", alpha);
  1065.                                                 FPuts(outfile, buffer);
  1066.                                         }
  1067.                                                        
  1068.                                         for(node = (struct node *)nodelist->mlh_Head, match=0; node->nextnode.mln_Succ; node = (struct node *)node->nextnode.mln_Succ)
  1069.                                                 if(!(stricmp(node->name, (char *)tree->text->node)))
  1070.                                                 {
  1071.                                                         match =1;
  1072.                                                         break;
  1073.                                                 }
  1074.                                                 
  1075.                                         if(match)       
  1076.                                         {
  1077.                                                 sprintf(buffer," @{\" %s \" link \"%s\" %d}", tree->text->name, node->name, (struct link *)tree->text->linenumber);
  1078.                                                 FPuts(outfile, buffer);
  1079.                                                 for (i=0; i<(spacing-(strlen(tree->text->name))); i++)
  1080.                                                         FPutC(outfile, ' ');
  1081.                                                 sprintf(buffer, "%s\n", node->title);
  1082.                                                 FPuts(outfile,buffer);
  1083.                                          }
  1084.                                          else
  1085.                                          {
  1086.                                                 printf("  Can't find node for link \"%s\" - please double check reference.\n", tree->text->name); 
  1087.                                                 sprintf(buffer, "?@{\" %s \" link \"%s\" %d}\n", tree->text->name, (char *)tree->text->node, tree->text->linenumber);
  1088.                                                 FPuts(outfile, buffer);
  1089.                                          }
  1090.                                 }
  1091.                                 break;
  1092.                      }
  1093.                      
  1094.                 if(!(writeindex(tree->rightptr)))
  1095.                         return 0;
  1096.                 FreeMem(tree, sizeof(struct treenode));
  1097.                 }
  1098.    return 1;             
  1099. }
  1100.  
  1101. int insertnode(struct treenode **tree, struct word *current, BOOL Type)
  1102. {
  1103.         if(*tree == NULL)
  1104.         {
  1105.                 *tree = AllocMem(sizeof(struct treenode), MEMF_CLEAR);
  1106.                 
  1107.                 if (*tree != NULL)
  1108.                 {
  1109.                         (*tree)->text = current;
  1110.                         (*tree)->type = Type;
  1111.                         (*tree)->leftptr = NULL;
  1112.                         (*tree)->rightptr = NULL;
  1113.                 }
  1114.                 else
  1115.                 {
  1116.                         error("Could not allocate memory to insert word in tree!\n");
  1117.                         return 0;
  1118.                 }
  1119.         }
  1120.         else
  1121.         {
  1122.                 if(stricmp((*tree)->text->name, current->name) >= 0)
  1123.                         insertnode(&((*tree)->leftptr), current, Type);
  1124.                 else
  1125.                         insertnode(&((*tree)->rightptr), current, Type);
  1126.         }                
  1127.         return 1;
  1128. }
  1129.       
  1130.  
  1131.  
  1132.  
  1133.  
  1134. int GetPubScreen(void)
  1135. {
  1136.   if (!(Scr = LockPubScreen(PubScrName)))
  1137.     return(1L);
  1138.  
  1139.   if (!(VisualInfo = GetVisualInfo(Scr, TAG_DONE)))
  1140.     return(2L);
  1141.  
  1142.   if (!(ScrDrawInfo = GetScreenDrawInfo(Scr)))
  1143.     return(3L);
  1144.   return(0L);
  1145. }
  1146.  
  1147. void ClosePubScreen(void)
  1148. {
  1149.   if (VisualInfo)
  1150.     FreeVisualInfo(VisualInfo);
  1151.   if (Scr)
  1152.     UnlockPubScreen(NULL,  Scr);
  1153.   if (ScrDrawInfo)
  1154.     FreeScreenDrawInfo(Scr,  ScrDrawInfo);
  1155. }
  1156.  
  1157. int OpenIndexAGuiWindow(char windtitle[80])
  1158. {
  1159.   struct NewGadget    NewGad;
  1160.   struct Gadget       *Gad;
  1161.   register UWORD i, j;
  1162.   UWORD offsetx = Scr->WBorLeft;
  1163.   UWORD offsety = Scr->WBorTop + Scr->Font->ta_YSize + 1;
  1164.   int k=0;
  1165.   int LVStrGads[] = {ID_strExword, -1 };
  1166.  
  1167.  
  1168.   IndexAGuiStrExt.Font = NULL;
  1169.   IndexAGuiStrExt.Pens[0] = 1;
  1170.   IndexAGuiStrExt.Pens[1] = 0;
  1171.   IndexAGuiStrExt.ActivePens[0] = 1;
  1172.   IndexAGuiStrExt.ActivePens[1] = 0;
  1173.   IndexAGuiStrExt.InitialModes  = 0;
  1174.   IndexAGuiStrExt.EditHook = NULL;
  1175.   IndexAGuiStrExt.WorkBuffer = NULL;
  1176.  
  1177.   if (!(Gad = CreateContext(&IndexAGuiGList)))
  1178.       return(1L);
  1179.  
  1180.   butFileGad.TopEdge += kWindowOffSetY;
  1181.   butWords19Gad.TopEdge += kWindowOffSetY;
  1182.   for (i=0, j=0; i < IndexAGuiNumGads; i++)
  1183.   {
  1184.     CopyMem((char *)&IndexAGuiNGads[i], (char *)&NewGad, (long)sizeof(struct NewGadget));
  1185.  
  1186.     NewGad.ng_VisualInfo = VisualInfo;
  1187.     NewGad.ng_LeftEdge += offsetx;
  1188.     NewGad.ng_TopEdge  += offsety;
  1189.  
  1190.     if (IndexAGuiNTags[j] == GTLV_ShowSelected && IndexAGuiNTags[j+1] == 99)
  1191.       IndexAGuiNTags[j+1] = (ULONG)IndexAGuiGadgets[LVStrGads[k++]];
  1192.     IndexAGuiGadgets[i] = Gad = CreateGadgetA((ULONG)IndexAGuiGadTypes[i], Gad, &NewGad,
  1193.     (struct TagItem *)&IndexAGuiNTags[j]);
  1194.     if (IndexAGuiGadTypes[i] == STRING_KIND || IndexAGuiGadTypes[i] == INTEGER_KIND)
  1195.     {
  1196.     IndexAGuiGadgets[i]->Flags |= GFLG_STRINGEXTEND;
  1197.     ((struct StringInfo *)IndexAGuiGadgets[i]->SpecialInfo)->Extension = &IndexAGuiStrExt;
  1198.     }
  1199.     while (IndexAGuiNTags[j])
  1200.         j +=2;
  1201.     j++;
  1202.     if (!Gad)
  1203.        return(2L);
  1204.   }
  1205.   IndexAGuiGadgets[i-1]->NextGadget = &butWords19Gad;
  1206.   if (!(IndexAGuiWnd = OpenWindowTags(NULL,
  1207.       WA_Left,    IndexAGuiLeft,
  1208.       WA_Top,     IndexAGuiTop,
  1209.       WA_Width,    IndexAGuiWidth,
  1210.       WA_Height,    IndexAGuiHeight + kWindowOffSetY,
  1211.       WA_NewLookMenus, TRUE,
  1212.       WA_IDCMP,    IDCMP_CLOSEWINDOW |  IDCMP_NEWSIZE | IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_VANILLAKEY ,
  1213.       WA_Flags,    WFLG_CLOSEGADGET | WFLG_DEPTHGADGET  |  WFLG_SMART_REFRESH | 
  1214.              WFLG_RMBTRAP |  WFLG_DRAGBAR ,
  1215.       WA_Gadgets,    IndexAGuiGList,
  1216.       WA_Title,    windtitle,
  1217.       WA_ScreenTitle,    "IndexAG "VERSIONNUMBER" ©1999 Sébastien Boisvert",
  1218.       WA_PubScreen,    Scr,
  1219.       WA_AutoAdjust,    TRUE,
  1220.       WA_MinWidth,    200,
  1221.       WA_MinHeight,    150,
  1222.       WA_MaxWidth,    800,
  1223.       WA_MaxHeight,    600,
  1224.       TAG_DONE)))
  1225.           return(3L);
  1226.  
  1227.   CreateIndexAGuiLists();
  1228.   DrawIndexAGuiObjs();
  1229.   GT_RefreshWindow(IndexAGuiWnd, NULL);
  1230.   RefreshGadgets(IndexAGuiGadgets[0], IndexAGuiWnd, NULL);
  1231.   return(0L);
  1232. }
  1233.  
  1234. void CloseIndexAGuiWindow(void)
  1235. {
  1236.   IndexAGuiLeft = IndexAGuiWnd->LeftEdge;
  1237.   IndexAGuiTop  = IndexAGuiWnd->TopEdge;
  1238.   if (IndexAGuiWnd)
  1239.     CloseWindow(IndexAGuiWnd);
  1240.   if (IndexAGuiGList)
  1241.     FreeGadgets(IndexAGuiGList);
  1242. }
  1243.  
  1244. int IndexAGuiHandler(void)
  1245. {
  1246.   struct IntuiMessage    *msg;
  1247.   struct VAobject    VAObject;
  1248.   int running    = 1;
  1249.   int (*func)(struct VAobject VAObject);
  1250.   ULONG class;
  1251.   UWORD code;
  1252.  
  1253.   while (msg=GT_GetIMsg(IndexAGuiWnd->UserPort))
  1254.   {
  1255.     CopyMem((char *)msg, (char *)&IndexAGuiMsg, (long)sizeof(struct IntuiMessage));
  1256.     class = msg->Class;
  1257.     code  = msg->Code;
  1258.  
  1259.     VAObject.va_Window = (struct Window *)IndexAGuiWnd;
  1260.     VAObject.va_Gadget = (struct Gadget *)msg->IAddress;
  1261.     VAObject.va_IntuiMsg = (struct IntuiMessage *)msg;
  1262.     VAObject.va_Flags = 0;
  1263.     VAObject.va_UserData = 0;
  1264.  
  1265.     GT_ReplyIMsg(msg);
  1266.     switch(class)
  1267.     {
  1268.  
  1269.       case IDCMP_NEWSIZE:
  1270.        break;
  1271.  
  1272.       case IDCMP_CLOSEWINDOW:
  1273.          return(0);
  1274.          break;
  1275.  
  1276.       case IDCMP_GADGETUP:
  1277.           case IDCMP_GADGETDOWN:
  1278.         func = (void *)((struct Gadget *)IndexAGuiMsg.IAddress)->UserData;
  1279.         if (func != NULL)
  1280.           running =  func(VAObject);
  1281.         break;
  1282.             
  1283.       case   IDCMP_VANILLAKEY:
  1284.         switch(code)
  1285.         {
  1286.           case 'v':
  1287.               case 'V':
  1288.             ButtonSelected(IndexAGuiWnd, IndexAGuiGadgets[0]);
  1289.                 butSaveObj(VAObject);
  1290.             break;
  1291.           case 'n':
  1292.               case 'N':
  1293.             ButtonSelected(IndexAGuiWnd, IndexAGuiGadgets[1]);
  1294.                 butNewObj(VAObject);
  1295.             break;
  1296.           case 'i':
  1297.               case 'I':
  1298.             ButtonSelected(IndexAGuiWnd, IndexAGuiGadgets[2]);
  1299.                 makeindexfile();
  1300.             break;
  1301.           case 'd':
  1302.               case 'D':
  1303.             ButtonSelected(IndexAGuiWnd, IndexAGuiGadgets[3]);
  1304.                 butDeleteObj(VAObject);
  1305.             break;
  1306.           case 'f':
  1307.               case 'F':
  1308.             ActivateGadget(IndexAGuiGadgets[4], IndexAGuiWnd, NULL);
  1309.             break;
  1310.           case 't':
  1311.               case 'T':
  1312.             ActivateGadget(IndexAGuiGadgets[5], IndexAGuiWnd, NULL);
  1313.             break;
  1314.           case 'w':
  1315.               case 'W':
  1316.             ActivateGadget(IndexAGuiGadgets[6], IndexAGuiWnd, NULL);
  1317.             break;
  1318.           case 's':
  1319.               case 'S':
  1320.             ActivateGadget(IndexAGuiGadgets[7], IndexAGuiWnd, NULL);
  1321.             break;
  1322.           case 'e':
  1323.               case 'E':
  1324.             ActivateGadget(IndexAGuiGadgets[8], IndexAGuiWnd, NULL);
  1325.             break;
  1326.               case 'o':
  1327.               case 'O':
  1328.             togglemx();
  1329.             break;
  1330.               case 'c':
  1331.               case 'C':
  1332.                 toggleck();
  1333.             break;
  1334.         }
  1335.         break;
  1336.     }
  1337.   }
  1338.   return(running);
  1339. }
  1340.  
  1341. void DrawIndexAGuiObjs(void)
  1342. {
  1343.   IndexAGuiDrawRects(IndexAGuiWnd);
  1344.  
  1345. }
  1346.  
  1347. int IndexAGuiMainHandler(void)
  1348. {
  1349.   int running = 1;
  1350.   ULONG windsig, signals;
  1351.  
  1352.   windsig = 1L << IndexAGuiWnd->UserPort->mp_SigBit;
  1353.  
  1354.   while (running == 1)
  1355.   {
  1356.     signals = Wait( windsig );
  1357.     if (signals & windsig)
  1358.     {
  1359.       running = IndexAGuiHandler();
  1360.     }
  1361.   }
  1362.   return(running);
  1363. }
  1364.  
  1365. void readprefs(void)
  1366. {
  1367.         BPTR prefsfile;
  1368.         char prefstemp[5]="";
  1369.         
  1370.         if(prefsfile=Open("IndexAG.prefs", MODE_OLDFILE))
  1371.         {
  1372.                 FGets(prefsfile,Wordpath,80);
  1373.                 strip(Wordpath, "\n", 'E');
  1374.                 FGets(prefsfile,WordFile,80);
  1375.                 FGets(prefsfile,groupstart,5);
  1376.                 FGets(prefsfile,groupend,5);
  1377.                 FGets(prefsfile,prefstemp,10);
  1378.                 threshold=atoi(prefstemp);
  1379.                 FGets(prefsfile,prefstemp,5);
  1380.                 nolinks=atoi(prefstemp);
  1381.                 nowords=!nolinks;
  1382.                 FGets(prefsfile,prefstemp,5);
  1383.                 comment=atoi(prefstemp);
  1384.                 Close(prefsfile);
  1385.         }
  1386.         strip(WordFile, "\n",'E');
  1387.         strip(groupstart, "\n",'E');
  1388.         strip(groupend,"\n",'E');
  1389.         readwords();
  1390. }
  1391.  
  1392. int main(int argc, char *argv[])
  1393. {
  1394.      mytext.FrontPen = ScrDrawInfo->dri_Pens[TEXTPEN]; 
  1395.      mytext.BackPen = ScrDrawInfo->dri_Pens[FILLPEN];
  1396.      mytext.DrawMode = JAM1;
  1397.      mytext.LeftEdge = 20;
  1398.      mytext.TopEdge = 20;
  1399.      mytext.ITextFont = &topaz8;
  1400.      mytext.IText = "This is a test";
  1401.      mytext.NextText = NULL;
  1402.      
  1403.      if (argc < 2 )
  1404.      {
  1405.         int rc;
  1406.         wbmode=TRUE;
  1407.         if(wbmode == TRUE && (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37))))
  1408.         {
  1409.                 printf("Cannot open graphics.library v37\n");
  1410.                 exit(0);
  1411.         }
  1412.  
  1413.    if (!(GetPubScreen()))
  1414.    {
  1415.     for (rc=0; rc < 1; rc++)
  1416.       IndexAGuiLists[rc]=GetNewList();
  1417.     if (!(OpenIndexAGuiWindow("IndexAG")))
  1418.     {
  1419.           readprefs();
  1420.           GT_SetGadgetAttrs(IndexAGuiGadgets[ID_strWord], IndexAGuiWnd, NULL, GTST_String, WordFile, TAG_END);
  1421.           GT_SetGadgetAttrs(IndexAGuiGadgets[ID_strStart], IndexAGuiWnd, NULL, GTST_String, groupstart, TAG_END);
  1422.           GT_SetGadgetAttrs(IndexAGuiGadgets[ID_strEnd], IndexAGuiWnd, NULL, GTST_String, groupend, TAG_END);
  1423.           GT_SetGadgetAttrs(IndexAGuiGadgets[ID_intThres], IndexAGuiWnd, NULL, GTIN_Number, threshold, TAG_END);
  1424.           GT_SetGadgetAttrs(IndexAGuiGadgets[ID_listExclude],IndexAGuiWnd, NULL, GTLV_Labels, exwords, TAG_END);
  1425.           GT_SetGadgetAttrs(IndexAGuiGadgets[ID_mxLinks],IndexAGuiWnd, NULL, GTMX_Active, !nolinks, TAG_END);
  1426.           GT_SetGadgetAttrs(IndexAGuiGadgets[ID_chkComment], IndexAGuiWnd, NULL, GTCB_Checked, -(comment), TAG_END); 
  1427.  
  1428.       rc = IndexAGuiMainHandler();
  1429.           wbmode=FALSE;
  1430.       CloseIndexAGuiWindow();
  1431.           cleanup();
  1432.     }
  1433.     for (rc=0; rc < 1; rc++)
  1434.       FreeList(IndexAGuiLists[rc]);
  1435.     ClosePubScreen();
  1436.         
  1437.    }
  1438.     CloseLibrary((struct Library *)GfxBase);
  1439.     return(0L);
  1440.   }
  1441.      else
  1442.      {
  1443.         if(readarguments())
  1444.         {
  1445.                 wbmode=FALSE;
  1446.                         makeindexfile();
  1447.         }
  1448.      }
  1449.      
  1450. }
  1451. void makeindexfile(void)
  1452. {
  1453.         char file[160];
  1454.         strcpy(file,Guidepath);
  1455.         AddPart(file,GuideName, 160);
  1456.         if (!(masterfile=Open(file, MODE_OLDFILE)))
  1457.         {
  1458.             char errorstr[80]="Could not open file ";
  1459.             strcat(errorstr, GuideName);
  1460.             strcat(errorstr, "!\n");
  1461.             error(errorstr);
  1462.         }
  1463.         else
  1464.         {
  1465.            Filelock=Lock(GuideName,SHARED_LOCK);
  1466.            Examine(Filelock, &Fileinfo);
  1467.            UnLock(Filelock);
  1468.            filesize = Fileinfo.fib_Size;
  1469.            AGget(masterfile, buffer, 513);
  1470.                    
  1471.            if (strnicmp(buffer, "@DATABASE", 9))
  1472.               error("Not an AmigaGuide Database!\n");
  1473.            else
  1474.            {
  1475.               if (!nowords && !wbmode)
  1476.                  readwords();
  1477.                  
  1478.               if(!nolinks)
  1479.               {
  1480.                   if(!(linklist=AllocMem(sizeof(struct MinList), MEMF_CLEAR)))
  1481.                   {
  1482.                     error("Can't allocate node list structure!\n");
  1483.                        goto exit;
  1484.                   }
  1485.                   else
  1486.                     NewList((struct List *)linklist);
  1487.                } 
  1488.  
  1489.               
  1490.               if (!(nodelist=AllocMem(sizeof(struct MinList), MEMF_CLEAR)))
  1491.                  error("Not enough memory to create new nodelist!\n");
  1492.               else
  1493.               {
  1494.                  NewList((struct List *)nodelist);
  1495.                  
  1496.                  if(!wbmode)
  1497.                  {
  1498.                         printf("\nScanning document...   ");                 
  1499.                         fflush(stdout);
  1500.                  }
  1501.                 
  1502.                  AGget(masterfile, buffer, 513);
  1503.                  
  1504.                  do
  1505.                  {
  1506.                     tempword=strtok(buffer, " ");
  1507.                     if (!(strnicmp(tempword, "@NODE", 5)))
  1508.                     {
  1509.                       if(!scannode())
  1510.                           goto exit;
  1511.                           
  1512.                     }
  1513.                  }
  1514.                  while(AGget(masterfile, buffer, 513));    
  1515.                  
  1516.               }
  1517.               if(!(outfile = Open("index.node", MODE_NEWFILE)))
  1518.                         error("Can't create \"index.guide\" for output!\n");
  1519.                else
  1520.                {
  1521.                     spacing+=3;
  1522.                     FPuts(outfile, "@NODE Index\n@REMARK This index created with IndexAG "VERSIONNUMBER" by Sébastien Boisvert\n\n");
  1523.                     if(!(createindex()))
  1524.                         error("Could not create index!\n");
  1525.                     else
  1526.                     {
  1527.                         treeptr=NULL;
  1528.                         if(!wbmode)
  1529.                                 printf("\nDone!\n");
  1530.                     }
  1531.                     FPuts(outfile, "@ENDNODE\n");
  1532.                     Close(outfile);
  1533.                }
  1534.                
  1535.               exit:
  1536.               if(!wbmode)
  1537.                  cleanup();                 
  1538.            }
  1539.            Close(masterfile);
  1540.         }
  1541.         
  1542.      
  1543. #if DEBUG >=3
  1544.     MWReport("IndexAG memory report", MWR_FULL);
  1545. #endif    
  1546.  
  1547. }
  1548.  
  1549. unsigned char *AGget(BPTR file_get, char *buff, int length)
  1550. {
  1551.  
  1552.         unsigned char *result;       
  1553.         float size;
  1554.         int filepos=Seek(masterfile,0,OFFSET_CURRENT);
  1555.  
  1556.  
  1557.  
  1558.         result=FGets(file_get, buff, length);
  1559.  
  1560.         if (wbmode == FALSE)
  1561.         {
  1562.                 printf("\b\b\b%2.0f%", ((float)filepos / filesize) * 100);
  1563.                 fflush(stdout);
  1564.         }
  1565.         else
  1566.         {
  1567.                 /*SetWrMsk(IndexAGuiWnd->RPort,251 )*/
  1568.                 SetAPen(IndexAGuiWnd->RPort, ScrDrawInfo->dri_Pens[FILLPEN]);
  1569.                 SetDrMd(IndexAGuiWnd->RPort, JAM1);
  1570.                 size = (float)filepos/filesize;
  1571.                 RectFill(IndexAGuiWnd->RPort, 15, 24, 15+(LONG)(234*size), 46);
  1572.                 PrintIText(IndexAGuiWnd->RPort, &mytext, 10, 10);
  1573.         }
  1574.  
  1575.         return result;
  1576. }
  1577.